home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Utilities Experience
/
The Utilities Experience - Volume 1.iso
/
software
/
icons+tools
/
associate_v1.5
/
source
/
associate.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-01-11
|
20KB
|
831 lines
/* Associate (C) 1995 Dominic Clifton - AKA Hydra/LSD */
// note: you MUST have a global define KS20 or KS30 set or CRASH!!!
// I use SCOptions to set it...
#define MAIN
#include "includes.h"
static UBYTE *VersTag = "$VER: Associate 1.5 (13.01.1996)";
#include "vars.h"
#include <wb2cli.h>
char *iconname="Progdir:Associate";
char msgstr[300];
BOOL done=FALSE;
char cfgname[]="S:Associate.cfg";
BOOL All,ttall,AllThis;
LONG ttallval;
ULONG doalldrawers=0;
struct TypeNode *MatchType;
LONG IconsToProcess;
/*
SHITTTTTTTTTTTTTTTTTTTTTT Nodes in a list that point to lists that point to
more nodes are VERY confusing! :-)
*/
// next four functions nicked from YAK source code.. ta very much..
// (but they are modified a bit tho..)
char __regargs *
TTString(struct DiskObject *diskobj,char *name, char *def)
{
char *what;
if (diskobj)
if (what = FindToolType(diskobj->do_ToolTypes, name))
return what;
return def;
}
/* like ArgInt() */
LONG __regargs
TTInt(struct DiskObject *diskobj,char *name, LONG def)
{
char *what;
if (diskobj)
if (what = FindToolType(diskobj->do_ToolTypes, name))
StrToLong(what, &def);
return def;
}
struct Node *GetNode(struct List *lh, UWORD n)
{
struct Node *ln;
for (ln = lh->lh_Head; n--; ln = ln->ln_Succ)
;
return ln;
}
UWORD GetNodeNum(struct List *lh, struct Node *node)
{
struct Node *ln;
UWORD i;
for (i = 0, ln = lh->lh_Head; ln != node; ln = ln->ln_Succ, i++)
;
return i;
}
// ok now for the bitchy list stuff..
void FreeNameList(struct List *FileList)
{
struct Node *Current,*Next;
if (Current=FileList->lh_Head)
{
while (FileList->lh_Head->ln_Succ)
{
Next=Current->ln_Succ;
if (Current->ln_Name)
{
free(Current->ln_Name);
}
Remove(Current);
FreeMem(Current,sizeof(struct Node));
Current=Next;
}
}
}
struct Node *NewNameNode(struct List *NameList,char *str)
{
struct Node *new=NULL;
if (new=AllocMem(sizeof(struct Node),MEMF_PUBLIC))
{
new->ln_Name=strdup(str);
AddTail(NameList,new);
}
return(new);
}
void FreeNameNode(struct Node *node)
{
if (node->ln_Name)
{
free(node->ln_Name);
}
}
void FreeTypeNode(struct TypeNode *new)
{
if (new->nameplist)
{
FreeNameList(new->nameplist);
FreeMem(new->nameplist,sizeof (struct List));
}
if (new->fileplist)
{
FreeNameList(new->fileplist);
FreeMem(new->fileplist,sizeof (struct List));
}
if (new->IconName) free(new->IconName);
FreeNameNode(&new->typenode);
}
void FreeTypeList(struct List *TypeList)
{
struct TypeNode *Current,*Next;
if (Current=(struct TypeNode*)TypeList->lh_Head)
{
while (TypeList->lh_Head->ln_Succ)
{
Next=(struct TypeNode *)Current->typenode.ln_Succ;
FreeTypeNode(Current);
Remove((struct Node*) Current);
FreeMem(Current,sizeof(struct TypeNode));
Current=Next;
}
}
}
short AllocTypeNode(struct TypeNode *new)
{
short retval=FALSE;
if (new->nameplist=AllocMem(sizeof(struct List),MEMF_ANY))
{
NewList(new->nameplist);
if (new->fileplist=AllocMem(sizeof(struct List),MEMF_ANY))
{
NewList(new->fileplist);
if (new->IconName=malloc(256))
{
new->IconName[0]='\0';
retval=TRUE;
}
}
}
return (retval);
}
struct TypeNode *NewTypeNode(struct List *TypeList,char *str)
{
struct TypeNode *new;
if (new=AllocMem(sizeof(struct TypeNode),MEMF_PUBLIC))
{
new->typenode.ln_Name=strdup(str); // I should REALLY error check this line.
new->nameplist=NULL; // initialize structure..
new->fileplist=NULL;
new->IconName=NULL;
new->RunInfo=0;
if (AllocTypeNode(new))
{
AddTail(TypeList,(struct Node *)new);
}
else
{
FreeTypeNode(new);
FreeMem(new,sizeof(struct TypeNode));
new=NULL;
}
}
return(new); // return NULL for fail or the pointer to the new structure..
}
void SetDefault( void )
{
struct TypeNode *mytn;
struct Node *mynode;
struct List *namelist;
mytn=NewTypeNode(typelist,"Picture");
if (mytn)
{
mytn->IconName="ENV:Sys/Def_Misc.info";
namelist=mytn->nameplist;
mynode=NewNameNode(namelist,"#?.PIC");
mynode=NewNameNode(namelist,"#?.GIF");
mynode=NewNameNode(namelist,"#?.JPG");
mynode=NewNameNode(namelist,"#?.JPEG");
mynode=NewNameNode(namelist,"#?.IFF");
mynode=NewNameNode(namelist,"#?.ILBM");
namelist=mytn->fileplist;
mynode=NewNameNode(namelist,"FORM????ILBM#?");
mynode=NewNameNode(namelist,"GIF#?");
}
mytn=NewTypeNode(typelist,"Source Code");
if (mytn)
{
mytn->IconName="ENV:Sys/def_Source.info";
namelist=mytn->nameplist;
mynode=NewNameNode(namelist,"#?.c");
mynode=NewNameNode(namelist,"#?.s");
mynode=NewNameNode(namelist,"#?.i");
mynode=NewNameNode(namelist,"#?.h");
mynode=NewNameNode(namelist,"#?.p");
mynode=NewNameNode(namelist,"#?.pas");
}
}
short SetUp( void )
{
short retval=FALSE;
if (ReqToolsBase = (struct ReqToolsBase *) OpenLibrary (REQTOOLSNAME, REQTOOLSVERSION))
{
if (typelist=AllocMem(sizeof(struct List),MEMF_ANY))
{
NewList(typelist);
if(IconBase = OpenLibrary("icon.library",37))
{
#ifdef KS20
if (WorkbenchBase=OpenLibrary("workbench.library",37))
#endif
#ifdef KS30
if (WorkbenchBase=OpenLibrary("workbench.library",39))
#endif
{
if (ascport=CreateMsgPort())
{
if (filereq = rtAllocRequestA (RT_FILEREQ, NULL))
{
retval=TRUE;
}
else rtEZRequest("Could not allocate requester",okstr,NULL,(struct TagItem *)&reqtags,NULL);
}
else rtEZRequest("Could Not Create Message Port!",okstr,NULL,(struct TagItem *)&reqtags,NULL);
}
#ifdef KS20
else rtEZRequest("You Need workbench.library v37+!",okstr,NULL,(struct TagItem *)&reqtags,NULL);
#endif
#ifdef KS30
else rtEZRequest("You Need workbench.library v39+!",okstr,NULL,(struct TagItem *)&reqtags,NULL);
#endif
}
else rtEZRequest("You Need icon.library v37!",okstr,NULL,(struct TagItem *)&reqtags,NULL);
}
else rtEZRequest("Unable to alloc memory!",okstr,NULL,(struct TagItem *)&reqtags,NULL);
}
return(retval);
}
void KillAppIcon( void )
{
if (appicon) RemoveAppIcon(appicon);
if (ascport)
{
while(appmsg=(struct AppMessage *)GetMsg(ascport))
ReplyMsg((struct Message *)appmsg);
}
}
void CleanUp( void )
{
KillAppIcon();
if ( ascport ) DeleteMsgPort(ascport);
if ( dobj ) FreeDiskObject(dobj);
if ( WorkbenchBase ) CloseLibrary(WorkbenchBase);
if ( IconBase ) CloseLibrary(IconBase);
if ( filereq ) rtFreeRequest (filereq);
if ( ReqToolsBase ) CloseLibrary ((struct Library *)ReqToolsBase);
if ( typelist )
{
FreeTypeList(typelist);
FreeMem(typelist,sizeof(struct List));
}
}
short OpenAppIcon( void )
{
short retval=FALSE;
if ((dobj=GetDiskObject(iconname))==NULL)
{
sprintf(msgstr,"Could Not Open \"%s.info\" to create the AppIcon\n"
"You might still have to rename associate, see the docs!",iconname);
rtEZRequest(msgstr,okstr,NULL,(struct TagItem *)&reqtags,NULL);
}
else
{
dobj->do_Type=NULL; // set to null for appicon..,
// temp fix until loadprefs has been written..
dobj->do_CurrentX=TTInt(dobj,"ICONX",NO_ICON_POSITION);
dobj->do_CurrentY=TTInt(dobj,"ICONY",NO_ICON_POSITION);
// wb don't like only one of the coords set.. :-)
if (dobj->do_CurrentX >= 0 && dobj->do_CurrentY == NO_ICON_POSITION) dobj->do_CurrentY=1;
if (dobj->do_CurrentY >= 0 && dobj->do_CurrentX == NO_ICON_POSITION) dobj->do_CurrentX=1;
if ((appicon=AddAppIconA(0L,0L,"Associate",ascport,NULL,dobj,NULL))==NULL)
{
rtEZRequest("Could Not Create App Icon!",okstr,NULL,(struct TagItem *)&reqtags,NULL);
}
else
{
retval=TRUE;
}
}
return(retval);
}
void DoOptions( void )
{
if (!SetupScreen())
{
if (!OpenAssociateWindow())
{
#ifdef KS20
LastTypeClicked=-1;
#endif
GT_SetGadgetAttrs(AssociateGadgets[GD_TypeList], AssociateWnd, NULL,
GTLV_Labels, (ULONG)typelist,
GTLV_Selected,0,
TAG_END);
UpdateLists();
do
{
Wait (1 << AssociateWnd->UserPort->mp_SigBit);
} while (HandleAssociateIDCMP());
CloseAssociateWindow();
}
CloseDownScreen();
}
}
void CreateIcon(char *filename, struct TypeNode *tnode)
{
char *iconname;
struct DiskObject *icn,*org=NULL;
int offset,orgoffset,newoffset;
char **ttypes=NULL,**oldttypes,*str;
BOOL cancel=FALSE;
iconname=strdup(tnode->IconName);
removeinfo(iconname);
if (icn=GetDiskObject(iconname))
{
icn->do_CurrentX=NO_ICON_POSITION;
icn->do_CurrentY=NO_ICON_POSITION;
// Added this next bit for v1.3
if (org=GetDiskObject(filename))
{
if (org->do_ToolTypes && org->do_ToolTypes[0])
{
offset=0;
while (icn->do_ToolTypes[offset]) offset++;
orgoffset=0;
while (org->do_ToolTypes[orgoffset]) orgoffset++;
// save old pointer
oldttypes=icn->do_ToolTypes;
if (str=AllocVec(strlen(filename)+40,MEMF_CLEAR))
{
sprintf(str,"An Icon Already Exists for file\n\"%s\"",filename);
if (!ttall) ttallval=rtEZRequest(str,"_Add New ToolTypes|_Old ToolTypes Only|_New ToolTypes Only|_Skip",NULL,(struct TagItem *)&reqtags,NULL);
switch (ttallval)
{
case 1:
if (ttypes=(char **)AllocVec((1+offset+orgoffset)*sizeof(LONG),MEMF_PUBLIC|MEMF_CLEAR))
{
newoffset=0;
offset=0;
while (icn->do_ToolTypes[offset])
{
ttypes[newoffset]=icn->do_ToolTypes[offset];
offset++;
newoffset++;
}
offset=0;
while (org->do_ToolTypes[offset])
{
ttypes[newoffset]=org->do_ToolTypes[offset];
offset++;
newoffset++;
}
icn->do_ToolTypes=ttypes;
}
break;
case 2:
icn->do_ToolTypes=org->do_ToolTypes;
break;
/*
case 3:
break;
*/
case 0:
cancel=TRUE;
break;
}
FreeVec(str);
if ((!cancel) && (IconsToProcess>0) && (!ttall))
{
if (rtEZRequest("Repeat for remaining icons ?","_Yes|_No",NULL,(struct TagItem *)&reqtags,NULL))
{
ttall=TRUE;
}
}
}
}
}
if (!cancel) PutDiskObject(filename,icn);
if (ttypes)
{
icn->do_ToolTypes=oldttypes; // restore old pointer so AmigaDOS can free it..
}
FreeDiskObject(icn);
if (org)
{
FreeDiskObject(org);
if (ttypes) FreeVec(ttypes); // and we free our own set here..
}
if (tnode->RunInfo)
{
DoInfo(filename);
}
free(iconname);
}
else
{
rtEZRequest("Error: Can't open \"%s.info\"\nCheck your config",okstr,NULL,(struct TagItem *)&reqtags,iconname);
}
}
void PickType(char *filename)
{
if (!SetupScreen())
{
if (!OpenPickWindow())
{
#ifdef KS20
LastPickClicked=-1;
#endif
GT_SetGadgetAttrs(PickGadgets[GD_PickType], PickWnd, NULL,
GTLV_Labels, (ULONG)typelist,
GTLV_Selected,0,
TAG_END);
do
{
Wait (1 << PickWnd->UserPort->mp_SigBit);
} while (HandlePickIDCMP());
// this is the only place temptnode is relied on between functions..
// so be carefull
if (temptnode) // idcmp handling will set this to NULL if pickwindow is cancelled
{
CreateIcon(filename,temptnode);
}
ClosePickWindow();
}
CloseDownScreen();
}
}
BOOL MatchFile(char *matchpattern, char *filename)
{
BPTR File;
char *buffer;
LONG buflen;
BOOL retval=FALSE;
char match[256];
short loop;
if (buffer=malloc(21))
{
if (File=Open(filename,MODE_OLDFILE))
{
if (buflen=Read(File,buffer,20)) // read 1st 20 bytes
{
for (loop=0;loop<buflen;loop++) // and check..
{
if (buffer[loop]==0) buffer[loop]='.'; // replace null bytes with .'s..
}
ParsePatternNoCase(matchpattern,match,255);
if (MatchPatternNoCase(match,buffer))
{
retval=TRUE;
}
}
Close(File);
}
free(buffer);
}
return(retval);
}
LONG MatchOK(char *filename,struct TypeNode *tnode)
{
LONG result;
MatchType=tnode;
if (!All)
{
sprintf(msgstr,"Matched file \"%s\" against\n"
"type \"%s\"\n"
"Do you want to use this type\n"
"or continue searching ?",FilePart(filename),tnode->typenode.ln_Name);
result=rtEZRequest(msgstr,"OK!|_All First|All _This|Continue..",NULL,(struct TagItem *)&reqtags,NULL);
if (result==2) All=TRUE;
if (result==3)
{
All=TRUE;
AllThis=TRUE;
}
return(result);
}
else return(1);
}
void DoIcon( char *filename)
{
struct TypeNode *tnode;
struct Node *node;
char match[256];
char temp;
LONG Matched=FALSE;
char *iconname;
struct DiskObject *icn;
temp=filename[strlen(filename)-1];
if (temp!='/' && temp!=':')
{
if (!AllThis)
{
for (tnode = (struct TypeNode *) typelist->lh_Head ; !Matched && tnode->typenode.ln_Succ ; tnode = (struct TypeNode *)tnode->typenode.ln_Succ)
{
for (node = tnode->nameplist->lh_Head ; !Matched && node->ln_Succ ; node = node->ln_Succ)
{
ParsePatternNoCase(node->ln_Name,match,255);
if (MatchPatternNoCase(match,FilePart(filename)))
{
Matched=MatchOK(filename,tnode);
}
}
if (!Matched)
{
for (node = tnode->fileplist->lh_Head ; !Matched && node->ln_Succ ; node = node->ln_Succ)
{
if (MatchFile(node->ln_Name,filename))
{
Matched=MatchOK(filename,tnode);
}
}
}
}
}
else
{
Matched=TRUE;
}
if (Matched)
{
CreateIcon(filename,MatchType);
}
else
{
sprintf(msgstr,"Sorry, I could not find a match\n"
"for the file \"%s\"",FilePart(filename));
if (rtEZRequest(msgstr,"Select A Type|Skip",NULL,(struct TagItem *)&reqtags,NULL))
{
PickType(filename);
}
}
}
else
{
if (iconname=strdup(filename))
{
sprintf(msgstr,"Copy Default %s Icon \nto %s ?",temp == '/' ? "Drawer" : "Disk",iconname);
if (temp=='/')
{
if ((doalldrawers==2) || (doalldrawers=rtEZRequest(msgstr,"Yes|All|Cancel",NULL,(struct TagItem *)&reqtags,NULL)))
{
iconname[strlen(iconname)-1]=0;
if (icn=GetDiskObject("env:sys/def_drawer"))
{
icn->do_CurrentX=NO_ICON_POSITION;
icn->do_CurrentY=NO_ICON_POSITION;
PutDiskObject(iconname,icn);
FreeDiskObject(icn);
}
}
}
else // disk..
{
if (rtEZRequest(msgstr,"Yes|Cancel",NULL,(struct TagItem *)&reqtags,NULL))
{
strcat(iconname,"disk");
if (icn=GetDiskObject("env:sys/def_disk"))
{
icn->do_CurrentX=NO_ICON_POSITION;
icn->do_CurrentY=NO_ICON_POSITION;
PutDiskObject(iconname,icn);
FreeDiskObject(icn);
}
}
}
free(iconname);
}
}
}
void CheckMessages( void )
{
short loop;
char *filename;
All=FALSE;
AllThis=FALSE;
MatchType=NULL;
doalldrawers=0;
ttall=FALSE;
ttallval=0;
while(appmsg=(struct AppMessage *)GetMsg(ascport))
{
if(appmsg->am_NumArgs==0L)
{
DoOptions();
}
else
if(appmsg->am_NumArgs>0L) // could it be less than 0 ?
{
IconsToProcess=appmsg->am_NumArgs;
if (filename=malloc(256))
{
for(loop=0;loop<appmsg->am_NumArgs;loop++)
{
IconsToProcess--;
NameFromLock(appmsg->am_ArgList[loop].wa_Lock,filename,255);
AddPart(filename,appmsg->am_ArgList[loop].wa_Name,255);
DoIcon(filename);
}
free(filename);
}
}
ReplyMsg((struct Message *)appmsg);
}
}
void stripcr( char *str)
{
if (str[strlen(str)-1]=='\n') str[strlen(str)-1]=0;
if (str[strlen(str)-1]=='\r') str[strlen(str)-1]=0;
}
void SavePrefs( void )
{
FILE *File;
struct TypeNode *tnode;
struct Node *node;
if (File=fopen(cfgname,"w"))
{
for (tnode = (struct TypeNode *) typelist->lh_Head ;tnode->typenode.ln_Succ ; tnode = (struct TypeNode *)tnode->typenode.ln_Succ)
{
fprintf(File,"|STARTLIST\n"
"%s\n" // node name
"%s\n" // icon name
"%d\n", // RunInfo
tnode->typenode.ln_Name,tnode->IconName,tnode->RunInfo);
if (tnode->nameplist->lh_Head->ln_Succ)
{
fprintf(File,"|NAMEPATTERN\n");
for (node = tnode->nameplist->lh_Head ;node->ln_Succ ; node = node->ln_Succ)
{
fprintf(File,"%s\n",node->ln_Name);
}
}
if (tnode->fileplist->lh_Head->ln_Succ)
{
fprintf(File,"|FILEPATTERN\n");
for (node = tnode->fileplist->lh_Head ;node->ln_Succ ; node = node->ln_Succ)
{
fprintf(File,"%s\n",node->ln_Name);
}
}
fprintf(File,"|ENDLIST\n");
}
fclose(File);
}
}
short LoadPrefs( void )
{
FILE *File;
char str[256];
char what='x';
// load prefs. return 1 if OK 0 otherwise..
if (File=fopen(cfgname,"r"))
{
while (!feof(File))
{
fgets(str,255,File);
if (!feof(File))
{
stripcr(str);
// ok, so i could use a "flag" here :-) buy hey! what do i care..
if (stricmp(str,"|ENDLIST")==0)
{
what='x';
}
else
{
if (stricmp(str,"|NAMEPATTERN")==0)
{
what='n';
}
else
{
if (stricmp(str,"|FILEPATTERN")==0)
{
what='f';
}
else
{
if (stricmp(str,"|STARTLIST")==0)
{
what='l';
}
else
{
if (what!='x')
{
switch(what)
{
case 'n':
NewNameNode(temptnode->nameplist,str);
break;
case 'f':
NewNameNode(temptnode->fileplist,str);
break;
case 'r':
sscanf(str,"%d",&temptnode->RunInfo);
what='x';
break;
case 'i':
strncpy(temptnode->IconName,str,255); // limited..
what='r';
break;
case 'l':
temptnode=NewTypeNode(typelist,str);
what='i';
break;
}
}
}
}
}
}
}
}
fclose(File);
return(1);
}
return(0);
}
void main(int argc,char *argv[])
{
WB2CLI((struct WBStartup *)argv,4000,DOSBase); /* so you get the default path! */
SetUp();
if (!LoadPrefs())
{
SetDefault();
DoOptions();
}
if (argc==2)
{
DoIcon(argv[1]);
}
else
{
if (OpenAppIcon())
{
while (!done)
{
WaitPort(ascport);
CheckMessages();
}
}
else
{
rtEZRequest("Could not create an AppIcon!","Quit!",NULL,(struct TagItem *)&reqtags,NULL);
}
}
CleanUp();
}